<?php

namespace App\Console\Commands;


use App\Events\CommandEnding;
use App\Events\CommandStarting;
use Illuminate\Console\Command;
use App\Console\Commands\Lib\ByNow;
use App\Console\Commands\Lib\ProcessTime;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;

abstract class BaseCommand extends Command
{
    use ByNow, ProcessTime;

    /**
     * BaseCommand constructor.
     */
    public function __construct()
    {
        $this->initNow();
        parent::__construct();
    }

    /**
     * 基类执行部分
     */
    public function handle()
    {
        $this->starting();
        $this->process();
        $this->ending();
    }

    /**
     * 脚本开始执行触发器
     */
    protected function starting()
    {
        // 记录执行开始时间
        $this->timeStart();
        event(new CommandStarting($this));
    }

    /**
     * 脚本执行部分
     * @return mixed
     */
    abstract public function process();

    /**
     * 脚本执行结束触发器
     */
    protected function ending()
    {
        // 记录执行结束时间
        $time = $this->timeEnd();
        event(new CommandEnding($this));
        $colorArr = ["blue"];
        // $colorArr = ["red", "blue", "yellow"];
        $rand_key = mt_rand(0, count($colorArr) - 1);

        // Custom colors
        $style = new OutputFormatterStyle($colorArr[$rand_key], null, array('bold', 'blink'));
        $this->output->getFormatter()->setStyle('fire', $style);
        $duration = '';
        list($hour, $minute, $second) = explode(' ', gmstrftime('%H %M %S', $time));

        if ($hour > 0) {
            $duration .= '<fire>' . (int)$hour . '</fire>小时';
        }
        if ($minute > 0) {
            $duration .= '<fire>' . (int)$minute . '</fire>分钟';
        }
        if ($second > 0) {
            $duration .= '<fire>' . (int)$second . '</fire>秒';
        }

        $this->output->writeln('本次执行共耗时:' . $duration  . PHP_EOL);
    }

    /**
     * 获取脚本签名 注意签名参数需要换行才能正常截取
     * @return string
     */
    public static function getSignature()
    {
        $command = new static();
        return current(explode(PHP_EOL, $command->signature));
    }

    /**
     * 基于某个事务执行结果的输出结果
     * @param bool $hasError 事务的执行结果
     * @param string $content 要输出的结果
     */
    protected function writeln($hasError, $content)
    {
        $func = $hasError ? 'comment' : 'info';
        $this->{$func}($content);
    }

    /**
     * 基于某个事务执行结果的输出结果
     * @param bool $hasError 事务的执行结果
     * @param string $content 要输出的结果
     */
    protected function writelnInline($hasError, $content)
    {
        $func = $hasError ? 'commentInline' : 'infoInline';
        $this->{$func}($content);
    }

    /**
     * 不换行的输出
     * @param $style
     * @param $message
     * @param null $verbosity
     */
    protected function writeInline($message, $style = null, $verbosity = null)
    {
        $styled = $style ? "<$style>$message</$style>" : $message;
        $this->output->write($styled, false, $this->parseVerbosity($verbosity));
    }

    /**
     * 不换行的输出
     * @param $message
     * @param null $verbosity
     */
    protected function infoInline($message, $verbosity = null)
    {
        $this->writeInline($message, 'info', $verbosity);
    }


    /**
     * 不换行的输出
     * @param $message
     * @param null $verbosity
     */
    protected function commentInline($message, $verbosity = null)
    {
        $this->writeInline($message, 'comment', $verbosity);
    }

    /**
     * 倒计时
     * @param $sec
     * @param string $text
     * @param null $verbosity
     */
    protected function countdown($sec, $text = '倒计时', $verbosity = null)
    {
        $this->commentInline("$text");
        do {
            $this->commentInline('.', $verbosity);
            $sec--;
            sleep(1);
        } while ($sec >= 0);
        $this->output->write(PHP_EOL);
    }
}
